# -*- coding: utf-8 -*-

import time
import sys
import os
from PIL import ImageFont
import cv2
import torch
from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtWidgets import (QApplication, QMainWindow, QFileDialog,
                             QMessageBox, QTableWidgetItem, QAbstractItemView, QDialog, QVBoxLayout, QLineEdit,
                             QPushButton, QLabel, QHBoxLayout)
from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal, QCoreApplication
from PyQt5.QtGui import QIcon, QPixmap

try:
    import qtawesome as qta

    QTAWESOME_AVAILABLE = True
except ImportError:
    QTAWESOME_AVAILABLE = False
    print("qtawesome not available, using text icons")

from ultralytics import YOLO

sys.path.append('UIProgram')
from UIProgram.UiMain import Ui_MainWindow
import detect_tools as tools
import Config
from UIProgram.precess_bar import ProgressBar

# ===========================================
# ✅ START: Simulated User Database
# ===========================================
# In a real application, this data should be stored securely in a database.
# For demonstration, we use a dictionary. The password should be hashed.
USER_DATA = {
    "admin": {
        "password": "password123",
        "security_question": "What is your favorite color?",
        "security_answer": "blue"
    }
}


# ===========================================
# ✅ END: Simulated User Database
# ===========================================


# ===========================================
# ✅ START: Added RegisterDialog Class
# ===========================================
class RegisterDialog(QDialog):
    """
    新用户注册对话框
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("注册新用户")
        self.setWindowIcon(QIcon("UIProgram/ui_imgs/icons/目标检测.png"))
        self.setFixedSize(450, 480)  # Slightly taller for more fields

        # --- 设置样式 (与ForgotPasswordDialog一致) ---
        self.setStyleSheet("""
            QDialog {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #2c3e50, stop:1 #34495e);
            }
            QLabel {
                color: #ecf0f1;
                font-size: 14px;
            }
            QLineEdit {
                background-color: rgba(0, 0, 0, 0.3);
                border: 1px solid #1abc9c;
                border-radius: 8px;
                padding: 8px;
                color: #ecf0f1;
                font-size: 14px;
            }
            QLineEdit:focus {
                border: 2px solid #1abc9c;
            }
            QPushButton {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #1abc9c, stop:1 #16a085);
                color: white;
                font-size: 16px;
                font-weight: bold;
                border: none;
                border-radius: 10px;
                padding: 10px;
            }
            QPushButton:hover {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #2ecc71, stop:1 #27ae60);
            }
            #cancelButton {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #e74c3c, stop:1 #c0392b);
            }
            #cancelButton:hover {
                 background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #ff6b6b, stop:1 #ee5a52);
            }
        """)

        # --- 创建控件 ---
        self.username_label = QLabel("👤 设置用户名:")
        self.username_input = QLineEdit(self)
        self.username_input.setPlaceholderText("请输入新用户名")

        self.password_label = QLabel("🔒 设置密码:")
        self.password_input = QLineEdit(self)
        self.password_input.setEchoMode(QLineEdit.Password)
        self.password_input.setPlaceholderText("请输入密码")

        self.confirm_password_label = QLabel("🔒 确认密码:")
        self.confirm_password_input = QLineEdit(self)
        self.confirm_password_input.setEchoMode(QLineEdit.Password)
        self.confirm_password_input.setPlaceholderText("请再次输入密码")

        self.security_question_label = QLabel("❓ 设置密保问题:")
        self.security_question_input = QLineEdit(self)
        self.security_question_input.setPlaceholderText("例如: 我最喜欢的颜色是?")

        self.security_answer_label = QLabel("🔑 设置密保答案:")
        self.security_answer_input = QLineEdit(self)
        self.security_answer_input.setPlaceholderText("例如: 蓝色 (请牢记)")

        self.register_button = QPushButton("立即注册")
        self.cancel_button = QPushButton("取消")
        self.cancel_button.setObjectName("cancelButton")

        # --- 布局 ---
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(40, 30, 40, 30)
        main_layout.setSpacing(10)

        main_layout.addWidget(self.username_label)
        main_layout.addWidget(self.username_input)
        main_layout.addWidget(self.password_label)
        main_layout.addWidget(self.password_input)
        main_layout.addWidget(self.confirm_password_label)
        main_layout.addWidget(self.confirm_password_input)
        main_layout.addWidget(self.security_question_label)
        main_layout.addWidget(self.security_question_input)
        main_layout.addWidget(self.security_answer_label)
        main_layout.addWidget(self.security_answer_input)

        button_layout = QHBoxLayout()
        button_layout.setSpacing(20)
        button_layout.addWidget(self.cancel_button)
        button_layout.addWidget(self.register_button)
        main_layout.addSpacing(20)
        main_layout.addLayout(button_layout)

        # --- 连接信号 ---
        self.register_button.clicked.connect(self.handle_registration)
        self.cancel_button.clicked.connect(self.reject)

    def handle_registration(self):
        """处理新用户注册逻辑"""
        username = self.username_input.text()
        password = self.password_input.text()
        confirm = self.confirm_password_input.text()
        question = self.security_question_input.text()
        answer = self.security_answer_input.text()

        # 1. 验证所有字段是否为空
        if not all([username, password, confirm, question, answer]):
            QMessageBox.warning(self, "错误", "所有字段均为必填项！")
            return

        # 2. 验证用户名是否已被占用
        if username in USER_DATA:
            QMessageBox.warning(self, "错误", f"用户名 '{username}' 已被占用，请更换一个！")
            return

        # 3. 验证两次密码是否一致
        if password != confirm:
            QMessageBox.warning(self, "错误", "两次输入的密码不一致！")
            self.password_input.clear()
            self.confirm_password_input.clear()
            self.password_input.setFocus()
            return

        # 4. 验证通过，注册新用户 (模拟)
        new_user_data = {
            "password": password,
            "security_question": question,
            "security_answer": answer
        }
        USER_DATA[username] = new_user_data

        print(f"✅ 新用户注册成功: {username}, 数据: {new_user_data}")

        QMessageBox.information(self, "注册成功", f"恭喜，账户 '{username}' 已成功创建！\n您现在可以使用新账户登录。")
        self.accept()  # 关闭注册对话框


# ===========================================
# ✅ END: Added RegisterDialog Class
# ===========================================


class ForgotPasswordDialog(QDialog):
    """
    忘记密码对话框，通过密保问题重置密码
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("重置密码")
        self.setWindowIcon(QIcon("UIProgram/ui_imgs/icons/目标检测.png"))
        self.setFixedSize(450, 400)

        # --- 设置样式 ---
        self.setStyleSheet("""
            QDialog {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #2c3e50, stop:1 #34495e);
            }
            QLabel {
                color: #ecf0f1;
                font-size: 14px;
            }
            QLineEdit {
                background-color: rgba(0, 0, 0, 0.3);
                border: 1px solid #1abc9c;
                border-radius: 8px;
                padding: 8px;
                color: #ecf0f1;
                font-size: 14px;
            }
            QLineEdit:focus {
                border: 2px solid #1abc9c;
            }
            QPushButton {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #1abc9c, stop:1 #16a085);
                color: white;
                font-size: 16px;
                font-weight: bold;
                border: none;
                border-radius: 10px;
                padding: 10px;
            }
            QPushButton:hover {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #2ecc71, stop:1 #27ae60);
            }
            #cancelButton {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #e74c3c, stop:1 #c0392b);
            }
            #cancelButton:hover {
                 background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #ff6b6b, stop:1 #ee5a52);
            }
        """)

        # --- 创建控件 ---
        self.username_label = QLabel("👤 用户名:")
        self.username_input = QLineEdit(self)
        self.username_input.setPlaceholderText("请输入您的用户名")

        self.security_question_label = QLabel("❓ 密保问题:")
        self.security_question_display = QLabel("...")  # Placeholder
        self.security_question_display.setStyleSheet("font-style: italic; color: #bdc3c7;")

        self.security_answer_label = QLabel("🔑 密保答案:")
        self.security_answer_input = QLineEdit(self)
        self.security_answer_input.setPlaceholderText("请输入密保问题的答案")

        self.new_password_label = QLabel("🔒 新密码:")
        self.new_password_input = QLineEdit(self)
        self.new_password_input.setEchoMode(QLineEdit.Password)
        self.new_password_input.setPlaceholderText("请输入新密码")

        self.confirm_password_label = QLabel("🔒 确认新密码:")
        self.confirm_password_input = QLineEdit(self)
        self.confirm_password_input.setEchoMode(QLineEdit.Password)
        self.confirm_password_input.setPlaceholderText("请再次输入新密码")

        self.reset_button = QPushButton("重置密码")
        self.cancel_button = QPushButton("取消")
        self.cancel_button.setObjectName("cancelButton")

        # --- 布局 ---
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(40, 30, 40, 30)
        main_layout.setSpacing(10)

        main_layout.addWidget(self.username_label)
        main_layout.addWidget(self.username_input)
        main_layout.addWidget(self.security_question_label)
        main_layout.addWidget(self.security_question_display)
        main_layout.addWidget(self.security_answer_label)
        main_layout.addWidget(self.security_answer_input)
        main_layout.addWidget(self.new_password_label)
        main_layout.addWidget(self.new_password_input)
        main_layout.addWidget(self.confirm_password_label)
        main_layout.addWidget(self.confirm_password_input)

        button_layout = QHBoxLayout()
        button_layout.setSpacing(20)
        button_layout.addWidget(self.cancel_button)
        button_layout.addWidget(self.reset_button)
        main_layout.addSpacing(20)
        main_layout.addLayout(button_layout)

        # --- 连接信号 ---
        self.username_input.editingFinished.connect(self.fetch_security_question)
        self.reset_button.clicked.connect(self.handle_password_reset)
        self.cancel_button.clicked.connect(self.reject)

    def fetch_security_question(self):
        """当用户输入完用户名后，获取并显示对应的密保问题"""
        username = self.username_input.text()
        if username in USER_DATA:
            question = USER_DATA[username]["security_question"]
            self.security_question_display.setText(question)
        else:
            self.security_question_display.setText("该用户不存在！")

    def handle_password_reset(self):
        """处理密码重置逻辑"""
        username = self.username_input.text()
        answer = self.security_answer_input.text()
        new_password = self.new_password_input.text()
        confirm_password = self.confirm_password_input.text()

        # 1. 验证用户是否存在
        if username not in USER_DATA:
            QMessageBox.warning(self, "错误", "用户名不存在！")
            return

        # 2. 验证密保答案
        if answer.lower() != USER_DATA[username]["security_answer"].lower():
            QMessageBox.warning(self, "错误", "密保答案不正确！")
            return

        # 3. 验证新密码
        if not new_password:
            QMessageBox.warning(self, "错误", "新密码不能为空！")
            return
        if new_password != confirm_password:
            QMessageBox.warning(self, "错误", "两次输入的密码不一致！")
            return

        # 4. 更新密码 (模拟)
        USER_DATA[username]["password"] = new_password
        print(f"Success: Password for user '{username}' has been updated to '{new_password}'.")

        QMessageBox.information(self, "成功", "密码已成功重置！")
        self.accept()  # 关闭对话框


class LoginDialog(QDialog):
    """
    用户登录对话框
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("AI系统登录")
        self.setWindowIcon(QIcon("UIProgram/ui_imgs/icons/目标检测.png"))
        self.setFixedSize(400, 320)  # 高度保持不变

        # --- 设置样式 ---
        self.setStyleSheet("""
            QDialog {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #0f2027, stop:0.5 #203a43, stop:1 #2c5364);
            }
            QLabel {
                color: #ffffff;
                font-size: 14px;
                font-weight: bold;
            }
            QLineEdit {
                background-color: rgba(0, 0, 0, 0.4);
                border: 1px solid #00d4ff;
                border-radius: 8px;
                padding: 8px;
                color: #ffffff;
                font-size: 14px;
            }
            QLineEdit:focus {
                border: 2px solid #00d4ff;
            }
            QPushButton {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #00d4ff, stop:1 #0099cc);
                color: white;
                font-size: 16px;
                font-weight: bold;
                border: none;
                border-radius: 10px;
                padding: 10px;
            }
            QPushButton:hover {
                background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                    stop:0 #4de6ff, stop:1 #00aaff);
            }
            QPushButton:pressed {
                background-color: #0099cc;
            }

            /* Style for the 'Forgot Password' button */
            #forgotPasswordBtn {
                background-color: transparent;
                border: none;
                color: #00e6ff;
                font-size: 12px;
                font-weight: normal;
                text-align: right;
            }
            #forgotPasswordBtn:hover {
                color: #ffffff;
                text-decoration: underline;
            }

            /* ✅ Style for the 'Register' button */
            #registerBtn {
                background-color: transparent;
                border: none;
                color: #00e6ff; /* Match the 'forgot' link color */
                font-size: 12px;
                font-weight: normal;
                text-align: left; /* Align left */
            }
            #registerBtn:hover {
                color: #ffffff;
                text-decoration: underline;
            }
        """)

        # --- 创建控件 ---
        self.username_label = QLabel("👤 用户名:")
        self.username_input = QLineEdit(self)
        self.username_input.setPlaceholderText("请输入用户名")
        self.username_input.setText("admin")  # 默认填入admin方便测试

        self.password_label = QLabel("🔑 密  码:")
        self.password_input = QLineEdit(self)
        self.password_input.setPlaceholderText("请输入密码")
        self.password_input.setEchoMode(QLineEdit.Password)

        self.login_button = QPushButton("登 录")
        self.cancel_button = QPushButton("取 消")

        # 忘记密码按钮
        self.forgot_password_button = QPushButton("忘记密码?")
        self.forgot_password_button.setObjectName("forgotPasswordBtn")
        self.forgot_password_button.setCursor(Qt.PointingHandCursor)

        # ✅ 添加注册按钮
        self.register_button = QPushButton("注册新账户")
        self.register_button.setObjectName("registerBtn")
        self.register_button.setCursor(Qt.PointingHandCursor)

        # --- 布局 ---
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(40, 30, 40, 30)
        main_layout.setSpacing(15)

        main_layout.addWidget(self.username_label)
        main_layout.addWidget(self.username_input)
        main_layout.addWidget(self.password_label)
        main_layout.addWidget(self.password_input)

        # ✅ 注册和忘记密码的链接布局
        links_layout = QHBoxLayout()
        links_layout.addWidget(self.register_button)  # 注册在左
        links_layout.addStretch()
        links_layout.addWidget(self.forgot_password_button)  # 忘记密码在右
        main_layout.addLayout(links_layout)

        # 登录和取消按钮水平布局
        button_layout = QHBoxLayout()
        button_layout.setSpacing(20)
        button_layout.addWidget(self.cancel_button)
        button_layout.addWidget(self.login_button)

        main_layout.addSpacing(5)  # 调整间距
        main_layout.addLayout(button_layout)

        # --- 连接信号 ---
        self.login_button.clicked.connect(self.handle_login)
        self.cancel_button.clicked.connect(self.reject)
        self.password_input.returnPressed.connect(self.handle_login)
        self.forgot_password_button.clicked.connect(self.show_forgot_password_dialog)
        self.register_button.clicked.connect(self.show_register_dialog)  # ✅ 连接注册信号

    def handle_login(self):
        """
        处理登录逻辑
        """
        username = self.username_input.text()
        password = self.password_input.text()

        if username in USER_DATA and USER_DATA[username]["password"] == password:
            self.accept()
        else:
            QMessageBox.warning(self, "登录失败", "用户名或密码错误，请重试！")
            self.password_input.clear()
            self.username_input.selectAll()
            self.username_input.setFocus()

    def show_forgot_password_dialog(self):
        """
        显示忘记密码对话框
        """
        forgot_dialog = ForgotPasswordDialog(self)
        forgot_dialog.exec_()  # Show the dialog modally

    # ✅ 添加显示注册对话框的方法
    def show_register_dialog(self):
        """
        显示注册对话框
        """
        register_dialog = RegisterDialog(self)
        register_dialog.exec_()  # Show modally


class ThemeManager:
    """
    主题管理器 - 支持背景图片设置
    """

    def __init__(self, main_window):
        self.main_window = main_window
        self.current_theme = "ocean"

    @staticmethod
    def get_theme_colors(theme_name):
        """
        获取主题颜色配置 - 重新添加背景图片支持
        """
        themes = {
            "ocean": {
                "bg_start": "#2a547a", "bg_mid1": "#3b739f", "bg_mid2": "#5a91c0", "bg_end": "#7fc0e7",
                "primary": "#00e6ff", "primary_light": "#33ffff", "primary_dark": "#00aaff",
                "component_bg": "rgba(40, 90, 130, 0.7)", "component_bg_dark": "rgba(20, 45, 65, 0.9)",
                "text_light": "#ffffff", "text_dark": "#000000",
                "border_color": "rgba(0, 230, 255, 0.5)", "border_color_strong": "rgba(0, 230, 255, 0.7)",
                "save_btn_start": "#ffd700", "save_btn_end": "#ff8c00",
                "exit_btn_start": "#ff6b6b", "exit_btn_end": "#ee5a52",
                # ✅ 重新添加背景图片路径
                "background_image": "UIProgram/ui_imgs/backgrounds/ocean_bg.jpg"
            },
            "deep_tech": {
                "bg_start": "#0f2027", "bg_mid1": "#203a43", "bg_mid2": "#2c5364", "bg_end": "#4a6741",
                "primary": "#00d4ff", "primary_light": "#4de6ff", "primary_dark": "#0099cc",
                "component_bg": "rgba(15, 32, 39, 0.8)", "component_bg_dark": "rgba(8, 16, 20, 0.9)",
                "text_light": "#ffffff", "text_dark": "#000000",
                "border_color": "rgba(0, 212, 255, 0.5)", "border_color_strong": "rgba(0, 212, 255, 0.7)",
                "save_btn_start": "#00ff88", "save_btn_end": "#00cc66",
                "exit_btn_start": "#ff4757", "exit_btn_end": "#ff3742",
                "background_image": "UIProgram/ui_imgs/backgrounds/tech_bg.png"
            },
            "eco_green": {
                "bg_start": "#2d5016", "bg_mid1": "#3e6b1f", "bg_mid2": "#4f7942", "bg_end": "#6faa6f",
                "primary": "#7ed321", "primary_light": "#a8e063", "primary_dark": "#5ba315",
                "component_bg": "rgba(45, 80, 22, 0.7)", "component_bg_dark": "rgba(22, 40, 11, 0.9)",
                "text_light": "#ffffff", "text_dark": "#000000",
                "border_color": "rgba(126, 211, 33, 0.5)", "border_color_strong": "rgba(126, 211, 33, 0.7)",
                "save_btn_start": "#f39c12", "save_btn_end": "#e67e22",
                "exit_btn_start": "#e74c3c", "exit_btn_end": "#c0392b",
                "background_image": "UIProgram/ui_imgs/backgrounds/eco_bg.jpg"
            }
        }
        return themes.get(theme_name, themes["ocean"])

    @staticmethod
    def get_base_style():
        """
        定义统一的基础样式模板 - 修复表格隔行换色问题
        """
        return """
            /* ===========================================
               主窗口样式 - 支持背景图片和渐变
               =========================================== */
            QMainWindow#MainWindow {{
                {background_style}
            }}

            /* ===========================================
               头部区域样式
               =========================================== */
            QWidget#header_widget {{
                background: {component_bg};
                border-radius: 12px;
                border: 1px solid {border_color};
            }}

            /* ===========================================
               组件容器样式
               =========================================== */
            QGroupBox {{
                background: {component_bg};
                border: 2px solid {border_color};
                border-radius: 12px;
                color: {primary};
                margin-top: 15px;
                padding-top: 10px;
            }}
            QGroupBox::title {{
                subcontrol-origin: margin; 
                left: 15px; 
                padding: 5px 15px;
                color: {primary}; 
                background: {component_bg_dark};
                border: 1px solid {border_color_strong}; 
                border-radius: 8px;
            }}

            /* ===========================================
               按钮样式
               =========================================== */
            QPushButton {{
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 {primary_dark}, stop:1 {primary});
                border: none; 
                border-radius: 10px; 
                color: {text_light};
                font-weight: bold;
                padding: 8px;
            }}
            QPushButton:hover {{
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 {primary}, stop:1 {primary_light});
                transform: translateY(-1px);
            }}
            QPushButton:pressed {{
                background: {primary_dark};
                transform: translateY(1px);
            }}
            #SaveBtn {{
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 {save_btn_start}, stop:1 {save_btn_end});
                color: {text_dark};
            }}
            #ExitBtn {{
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 {exit_btn_start}, stop:1 {exit_btn_end});
            }}

            /* ===========================================
               表格样式 - 修复隔行换色问题
               =========================================== */
            QTableWidget {{
                background-color: {component_bg}; 
                border: 1px solid {border_color};
                border-radius: 10px; 
                color: {text_light}; 
                selection-background-color: {primary};
                gridline-color: {border_color};
                alternate-background-color: rgba(255, 255, 255, 0.1);
            }}

            /* ✅ 修复：表格项样式 - 确保文字在所有背景下都清晰可见 */
            QTableWidget::item {{
                color: {text_light};
                padding: 8px;
                border: none;
            }}

            /* ✅ 修复：奇数行样式 */
            QTableWidget::item:alternate {{
                background-color: rgba(255, 255, 255, 0.05);
                color: {text_light};
            }}

            /* ✅ 修复：选中项样式 */
            QTableWidget::item:selected {{
                background-color: {primary};
                color: {text_dark};
            }}

            /* ✅ 修复：悬停效果 */
            QTableWidget::item:hover {{
                background-color: rgba(255, 255, 255, 0.15);
                color: {text_light};
            }}

            QHeaderView::section {{
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1, 
                    stop:0 {primary}, stop:1 {primary_dark});
                color: {text_light}; 
                padding: 10px; 
                border: none;
                font-weight: bold;
            }}

            /* ===========================================
               输入控件样式
               =========================================== */
            QDoubleSpinBox, QComboBox, QLineEdit {{
                background-color: {component_bg}; 
                border: 2px solid {border_color};
                border-radius: 8px; 
                padding: 6px 10px; 
                color: {text_light};
            }}
            QDoubleSpinBox:focus, QComboBox:focus, QLineEdit:focus {{
                border: 2px solid {primary};
                background-color: {component_bg_dark};
            }}

            /* ===========================================
               文本控件样式
               =========================================== */
            QCheckBox {{ 
                color: {text_light}; 
            }}
            QLabel {{ 
                color: {text_light}; 
                background-color: transparent; 
            }}
            #label_3, #label_12 {{ 
                color: {primary}; 
                font-weight: bold;
            }}
            #extra_desc {{ 
                color: {primary}; 
                opacity: 0.8; 
            }}
            #label_show {{
                background-color: rgba(0,0,0,0.1); 
                border: 2px dashed {border_color};
                border-radius: 20px;  /* ✅ 设置圆角半径 */
                color: {primary};
                padding: 5px;  /* ✅ 添加内边距，避免图片贴边 */
            }}
        """

    def apply_theme(self, theme_name):
        """应用指定主题 - 支持背景图片"""
        colors = self.get_theme_colors(theme_name)
        base_style = self.get_base_style()

        # ✅ 处理背景图片
        background_image_path = colors.get("background_image", "")
        if background_image_path and os.path.exists(background_image_path):
            # 使用背景图片
            background_style = f"""
                background-image: url({background_image_path});
                background-repeat: no-repeat;
                background-position: center;
                background-size: cover;
                background-attachment: fixed;
            """
            print(f"✅ 使用背景图片: {background_image_path}")
        else:
            # 使用渐变背景（备选方案）
            background_style = f"""
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 {colors['bg_start']}, stop:0.3 {colors['bg_mid1']}, 
                    stop:0.7 {colors['bg_mid2']}, stop:1 {colors['bg_end']});
            """
            print(f"⚠️ 背景图片不存在，使用渐变背景: {background_image_path}")

        # 应用样式
        final_stylesheet = base_style.format(
            background_style=background_style,
            **colors
        )

        self.main_window.setStyleSheet(final_stylesheet)
        self.current_theme = theme_name
        print(f"✅ 应用主题: {theme_name}")


class MainWindow(QMainWindow, Ui_MainWindow):
    """
    主窗口类 - 水面垃圾检测系统的主界面
    功能：图片检测、批量检测、视频检测、实时摄像头检测
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        # 延迟初始化确保界面完全加载
        QtCore.QTimer.singleShot(100, self.delayed_init)

    # ===========================================
    # 初始化方法组
    # ===========================================
    def create_rounded_pixmap(self, pixmap, radius=20):
        """
        创建圆角图片
        """
        if pixmap.isNull():
            return pixmap

        # 创建新的pixmap
        rounded_pixmap = QtGui.QPixmap(pixmap.size())
        rounded_pixmap.fill(Qt.transparent)

        # 创建画笔绘制圆角
        painter = QtGui.QPainter(rounded_pixmap)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform)

        # 创建圆角路径
        path = QtGui.QPainterPath()
        path.addRoundedRect(QtCore.QRectF(rounded_pixmap.rect()), radius, radius)

        # 设置裁剪区域并绘制原图
        painter.setClipPath(path)
        painter.drawPixmap(0, 0, pixmap)
        painter.end()

        return rounded_pixmap

    def update_display_with_rounded_image(self, image):
        """
        更新显示区域，应用圆角效果
        """
        try:
            # 原有的图像处理逻辑
            self.update_display_size()
            self.img_width, self.img_height = self.get_resize_size(image)

            if self.img_width <= 0 or self.img_height <= 0:
                return

            # 调整图像大小
            resize_cvimg = cv2.resize(image, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)

            if pix_img is None:
                return

            # ✅ 应用圆角效果
            rounded_pix_img = self.create_rounded_pixmap(pix_img, radius=20)

            # 设置到显示区域
            self.label_show.setPixmap(rounded_pix_img)
            self.label_show.setAlignment(Qt.AlignCenter)

        except Exception as e:
            print(f"❌ 圆角图片处理失败: {str(e)}")
    def delayed_init(self):
        """延迟初始化 - 确保界面完全加载后再进行配置"""
        self.theme_manager = ThemeManager(self)
        self.theme_manager.apply_theme("ocean")

        self.init_ui()
        self.init_parameters()
        self.init_signals()
        self.setup_tooltips()
        self.setup_ui_enhancements()
        self.add_theme_menu()
        # 添加统计功能集成
        self.init_statistics_integration()

    def init_ui(self):
        """初始化UI组件和基础设置"""
        # 显示区域尺寸设置
        self.show_width = max(800, self.label_show.width() - 10) if self.label_show.width() > 0 else 800
        self.show_height = max(600, self.label_show.height() - 10) if self.label_show.height() > 0 else 600

        # 初始化基础属性
        self.org_path = None
        self.is_camera_open = False
        self.cap = None
        self.device = 'cuda' if torch.cuda.is_available() else 'cpu'

        # 加载YOLO模型
        try:
            self.model = YOLO(Config.model_path, task='detect')
            print(f"✅ YOLO模型加载成功: {Config.model_path}")
        except Exception as e:
            QMessageBox.critical(self, '错误', f'YOLO模型加载失败: {str(e)}')
            return

        # # 字体设置
        # try:
        #     if os.path.exists("Font/platech.ttf"):
        #         self.fontC = ImageFont.truetype("Font/platech.ttf", 25, 0)
        #     else:
        #         self.fontC = ImageFont.load_default()
        #         print("⚠️ 使用默认字体")
        # except Exception as e:
        #     self.fontC = ImageFont.load_default()
        #     print(f"⚠️ 字体加载失败，使用默认字体: {e}")

        # 初始化工具类和定时器
        self.colors = tools.Colors()
        self.timer_camera = QTimer()
        self.timer_save_video = QTimer()

        # 表格设置 - 修复列宽问题
        self.setup_table_properties()

    def setup_table_properties(self):
        """设置表格属性 - 优化列宽分布和显示效果"""
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.setAlternatingRowColors(True)  # 启用隔行换色
        self.tableWidget.setGridStyle(Qt.NoPen)

        # ✅ 优化：设置行高
        self.tableWidget.verticalHeader().setDefaultSectionSize(35)

        # 设置列宽
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, header.ResizeToContents)
        header.setSectionResizeMode(1, header.Interactive)
        header.setSectionResizeMode(2, header.ResizeToContents)
        header.setSectionResizeMode(3, header.ResizeToContents)
        header.setSectionResizeMode(4, header.Stretch)

        self.tableWidget.setColumnWidth(0, 100)
        self.tableWidget.setColumnWidth(1, 600)
        self.tableWidget.setColumnWidth(2, 400)
        self.tableWidget.setColumnWidth(3, 400)

        header.setMinimumSectionSize(40)
        self.tableWidget.setWordWrap(False)
        self.tableWidget.setTextElideMode(Qt.ElideMiddle)

        # ✅ 优化：设置选择模式和焦点策略
        self.tableWidget.setFocusPolicy(Qt.NoFocus)  # 去除焦点框
        self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection)  # 单行选择


    def init_parameters(self):
        """初始化检测参数"""
        self.conf_thres = 0.25
        self.iou_thres = 0.45
        self.show_labels = True
        self.doubleSpinBox.setValue(self.conf_thres)
        self.doubleSpinBox_2.setValue(self.iou_thres)
        self.checkBox.setChecked(self.show_labels)

    def init_signals(self):
        """初始化信号连接"""
        # 按钮信号连接
        self.buttons["PicBtn"].clicked.connect(self.open_img)
        self.buttons["FilesBtn"].clicked.connect(self.detect_batch_imgs)
        self.buttons["VideoBtn"].clicked.connect(self.video_show)
        self.buttons["CapBtn"].clicked.connect(self.camera_show)
        self.buttons["SaveBtn"].clicked.connect(self.save_detect)
        self.buttons["ExitBtn"].clicked.connect(QCoreApplication.quit)

        # 参数控制信号连接
        self.comboBox.activated.connect(self.combox_change)
        self.doubleSpinBox.valueChanged.connect(self.update_conf_thres)
        self.doubleSpinBox_2.valueChanged.connect(self.update_iou_thres)
        self.checkBox.stateChanged.connect(self.update_show_labels)
        self.timer_camera.timeout.connect(self.open_frame)

    # ===========================================
    # UI增强方法组
    # ===========================================

    def add_theme_menu(self):
        """添加主题切换菜单 - 放大字体并改为白色"""
        try:
            menubar = self.menuBar()
            # ✅ 修复：更大字体的白色主题切换菜单样式
            menubar.setStyleSheet("""
                QMenuBar { 
                    background-color: transparent; 
                    font-size: 24px;  /* ✅ 增大字体 */
                    font-weight: 600;
                }
                QMenuBar::item { 
                    color: red;  /* ✅ 改为白色 */
                    background-color: rgba(255, 255, 255, 0.1); 
                    padding: 10px 20px;  /* ✅ 增大内边距 */
                    margin: 3px;
                    border-radius: 8px;  /* ✅ 增大圆角 */
                    border: 1px solid rgba(255, 255, 255, 0.3);
                    font-size: 16px;  /* ✅ 确保字体大小 */
                }
                QMenuBar::item:selected { 
                    background-color: rgba(255, 255, 255, 0.3); 
                    border: 1px solid rgba(255, 255, 255, 0.6);
                    color: white;  /* ✅ 保持白色 */
                }
                QMenuBar::item:hover { 
                    background-color: rgba(255, 255, 255, 0.2); 
                    color: white;  /* ✅ 悬停时也保持白色 */
                }
                QMenu { 
                    background-color: rgba(20, 45, 65, 0.95); 
                    color: white; 
                    border: 2px solid #00e6ff;
                    border-radius: 10px;  /* ✅ 增大圆角 */
                    font-size: 14px;  /* ✅ 菜单项字体大小 */
                }
                QMenu::item { 
                    padding: 10px 25px;  /* ✅ 增大菜单项内边距 */
                    margin: 3px;
                    color: white;  /* ✅ 确保菜单项为白色 */
                }
                QMenu::item:selected { 
                    background-color: #00e6ff; 
                    color: black;
                    border-radius: 6px;  /* ✅ 增大圆角 */
                }
            """)

            # ✅ 修复：更明显的菜单标题，更大字体
            theme_menu = menubar.addMenu('🎨 主题风格')
            themes = {
                '🌊 海洋蓝 (默认)': 'ocean',
                '💎 深海科技': 'deep_tech',
                '🌿 生态绿': 'eco_green'
            }
            for theme_name, theme_key in themes.items():
                action = theme_menu.addAction(theme_name)
                action.triggered.connect(lambda checked, key=theme_key: self.switch_theme(key))
        except Exception as e:
            print(f"主题菜单创建失败: {e}")

    def switch_theme(self, theme_name):
        """切换主题"""
        self.theme_manager.apply_theme(theme_name)

    def setup_tooltips(self):
        """设置工具提示"""
        tooltips = {
            self.buttons["PicBtn"]: "🖼️ 图片检测\n支持格式：JPG, PNG, JPEG, BMP\n快捷键：Ctrl+O",
            self.buttons["FilesBtn"]: "📁 批量检测\n选择文件夹进行批量处理\n自动识别所有支持格式",
            self.buttons["VideoBtn"]: "🎥 视频检测\n支持格式：AVI, MP4, WMV, MKV\n实时处理视频流",
            self.buttons["CapBtn"]: "📷 摄像头检测\n实时检测摄像头画面\n点击开启/关闭摄像头",
            self.buttons["SaveBtn"]: "💾 保存结果\n保存检测结果到本地\n支持图片和视频格式",
            self.buttons["ExitBtn"]: "🚪 退出系统\n安全退出应用程序\n快捷键：Alt+F4",
            self.doubleSpinBox: "🎯 置信度阈值\n设置检测的最小置信度\n范围：0.0 - 1.0",
            self.doubleSpinBox_2: "🔄 IoU阈值\n设置重叠框过滤阈值\n用于消除重复检测",
            self.checkBox: "🏷️ 显示标签\n是否在结果中显示类别标签和置信度分数"
        }
        for widget, tip in tooltips.items():
            widget.setToolTip(tip)

    def setup_ui_enhancements(self):
        """UI增强设置"""
        # ✅ 修复：移除qtawesome图标设置，避免与emoji重复
        # 只保留emoji图标，不再添加额外的qtawesome图标
        self.setWindowTitle("🌊 AI智能水面垃圾检测系统 - 生态环保·AI赋能")

    # ===========================================
    # 检测功能方法组
    # ===========================================

    def open_img(self):
        """打开单张图片进行检测"""
        self.close_camera_if_open()
        file_path, _ = QFileDialog.getOpenFileName(None, '打开图片', './', "Image files (*.jpg *.jpeg *.png *.bmp)")
        if not file_path:
            return
        self.pathStackedWidget.setCurrentWidget(self.PiclineEdit)
        self.org_path = file_path
        self.detect_and_display(file_path)

    def detect_and_display(self, path, is_batch=False):
        """执行检测并显示结果 - 增强错误处理和内存管理"""
        try:
            # 验证文件路径
            if not os.path.exists(path):
                QMessageBox.warning(self, '警告', f'文件不存在: {path}')
                return

            org_img = tools.img_cvread(path)
            if org_img is None:
                QMessageBox.warning(self, '警告', f'图片读取失败: {path}')
                return

            # 执行检测
            t1 = time.time()
            results = self.model(path, conf=self.conf_thres, iou=self.iou_thres)[0]
            t2 = time.time()
            self.time_lb.setText('{:.3f} s'.format(t2 - t1))

            # 安全获取检测结果
            self.location_list = []
            self.cls_list = []
            self.conf_list = []

            if results.boxes is not None and len(results.boxes) > 0:
                self.location_list = [list(map(int, e)) for e in results.boxes.xyxy.tolist()]
                self.cls_list = [int(i) for i in results.boxes.cls.tolist()]
                self.conf_list = ['%.2f %%' % (each * 100) for each in results.boxes.conf.tolist()]

            # 绘制检测结果
            now_img = results.plot(labels=self.show_labels)
            if now_img is None:
                print("⚠️ 结果绘制失败")
                return

            self.draw_img = now_img.copy()

            # ✅ 使用新的圆角显示方法
            self.update_display_with_rounded_image(now_img)

            if self.img_width <= 0 or self.img_height <= 0:
                print("⚠️ 图像尺寸计算错误")
                return

            resize_cvimg = cv2.resize(now_img, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)

            if pix_img is None:
                print("⚠️ 图像转换失败")
                return

            self.label_show.setPixmap(pix_img)
            self.label_show.setAlignment(Qt.AlignCenter)
            self.PiclineEdit.setText(path)

            # 更新检测信息
            self.update_detection_info()

            # 更新表格
            if not is_batch:
                self.tableWidget.setRowCount(0)
                self.tableWidget.clearContents()

            if self.location_list:
                self.table_info_show(self.location_list, self.cls_list, self.conf_list, path)

            if is_batch:
                self.tableWidget.scrollToBottom()
                QApplication.processEvents()

        except Exception as e:
            print(f"❌ 检测处理失败: {str(e)}")
            QMessageBox.critical(self, '错误', f'检测处理失败: {str(e)}')

    def update_detection_info(self):
        """更新检测信息显示"""
        target_nums = len(self.cls_list)
        self.label_nums.setText(str(target_nums))

        # 更新选择框
        choose_list = ['全部'] + [Config.names[id] + '_' + str(index) for index, id in enumerate(self.cls_list)]
        self.comboBox.clear()
        self.comboBox.addItems(choose_list)

        if target_nums >= 1:
            self.type_lb.setText(Config.CH_names[self.cls_list[0]])
            self.label_conf.setText(self.conf_list[0])
            self.label_xmin.setText(str(self.location_list[0][0]))
            self.label_ymin.setText(str(self.location_list[0][1]))
            self.label_xmax.setText(str(self.location_list[0][2]))
            self.label_ymax.setText(str(self.location_list[0][3]))
        else:
            self.clear_target_info()

    def detect_batch_imgs(self):
        """批量图片检测"""
        self.close_camera_if_open()
        directory = QFileDialog.getExistingDirectory(self, "选取文件夹", "./")
        if not directory:
            return
        self.pathStackedWidget.setCurrentWidget(self.PiclineEdit)
        self.org_path = directory
        img_suffix = ['jpg', 'png', 'jpeg', 'bmp']
        for file_name in os.listdir(directory):
            full_path = os.path.join(directory, file_name)
            if os.path.isfile(full_path) and file_name.split('.')[-1].lower() in img_suffix:
                self.detect_and_display(full_path, is_batch=True)

    def video_show(self):
        """视频检测"""
        self.close_camera_if_open()
        video_path, _ = QFileDialog.getOpenFileName(None, '打开视频', './', "Video files (*.avi *.mp4 *.wmv *.mkv)")
        if not video_path:
            return
        self.pathStackedWidget.setCurrentWidget(self.VideolineEdit)
        self.org_path = video_path
        self.VideolineEdit.setText(video_path)
        self.cap = cv2.VideoCapture(video_path)
        self.video_start()

    def camera_show(self):
        """摄像头检测"""
        self.is_camera_open = not self.is_camera_open
        self.pathStackedWidget.setCurrentWidget(self.CaplineEdit)
        if self.is_camera_open:
            self.CaplineEdit.setText('摄像头开启')
            self.cap = cv2.VideoCapture(0)
            self.video_start()
        else:
            self.CaplineEdit.setText('摄像头未开启')
            self.label_show.clear()
            self.close_camera_if_open()

    # ===========================================
    # 辅助方法组
    # ===========================================

    def update_display_size(self):
        """安全更新显示区域尺寸"""
        try:
            width = self.label_show.width()
            height = self.label_show.height()
            if width > 10 and height > 10:
                self.show_width = width - 10
                self.show_height = height - 10
            else:
                self.show_width = 800
                self.show_height = 600
        except Exception as e:
            print(f"⚠️ 显示区域尺寸更新失败: {e}")
            self.show_width = 800
            self.show_height = 600

    def get_resize_size(self, img):
        """计算图像显示尺寸"""
        try:
            if img is None:
                return 800, 600

            img_h, img_w = img.shape[:2]
            if img_h <= 0 or img_w <= 0:
                return 800, 600

            if self.show_width <= 0 or self.show_height <= 0:
                self.update_display_size()
            ratio = img_w / img_h
            if ratio >= self.show_width / self.show_height:
                return self.show_width, max(1, int(self.show_width / ratio))
            else:
                return max(1, int(self.show_height * ratio)), self.show_height
        except Exception as e:
            print(f"⚠️ 尺寸计算失败: {e}")
            return 800, 600

    def video_start(self):
        """启动视频处理"""
        self.tableWidget.setRowCount(0)
        self.tableWidget.clearContents()
        self.comboBox.clear()
        self.timer_camera.start(1)

    def open_frame(self):
        """处理视频帧"""
        ret, frame = self.cap.read()
        if ret:
            t1 = time.time()
            results = self.model(frame, conf=self.conf_thres, iou=self.iou_thres)[0]
            t2 = time.time()
            self.time_lb.setText('{:.3f} s'.format(t2 - t1))

            # 获取检测结果
            self.location_list = [list(map(int, e)) for e in results.boxes.xyxy.tolist()]
            self.cls_list = [int(i) for i in results.boxes.cls.tolist()]
            self.conf_list = ['%.2f %%' % (each * 100) for each in results.boxes.conf.tolist()]

            # 绘制结果
            now_img = results.plot(labels=self.show_labels)
            self.draw_img = now_img
            self.img_width, self.img_height = self.get_resize_size(now_img)
            resize_cvimg = cv2.resize(now_img, (self.img_width, self.img_height))
            pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
            self.label_show.setPixmap(pix_img)

            # 更新信息显示
            self.update_detection_info()

            # 更新表格
            self.table_info_show(self.location_list, self.cls_list, self.conf_list,
                                 "Camera" if self.is_camera_open else self.org_path)
        else:
            self.timer_camera.stop()
            if self.cap:
                self.cap.release()

    def combox_change(self):
        """处理目标选择框变化"""
        com_text = self.comboBox.currentText()
        if com_text == '全部':
            cur_img = self.draw_img
            if len(self.cls_list) > 0:
                self.type_lb.setText(Config.CH_names[self.cls_list[0]])
                self.label_conf.setText(self.conf_list[0])
                self.label_xmin.setText(str(self.location_list[0][0]))
                self.label_ymin.setText(str(self.location_list[0][1]))
                self.label_xmax.setText(str(self.location_list[0][2]))
                self.label_ymax.setText(str(self.location_list[0][3]))
        else:
            index = int(com_text.split('_')[-1])
            cur_img = self.draw_img.copy()
            self.type_lb.setText(Config.CH_names[self.cls_list[index]])
            self.label_conf.setText(self.conf_list[index])
            self.label_xmin.setText(str(self.location_list[index][0]))
            self.label_ymin.setText(str(self.location_list[index][1]))
            self.label_xmax.setText(str(self.location_list[index][2]))
            self.label_ymax.setText(str(self.location_list[index][3]))

        resize_cvimg = cv2.resize(cur_img, (self.img_width, self.img_height))
        pix_img = tools.cvimg_to_qpiximg(resize_cvimg)
        self.label_show.setPixmap(pix_img)

    def table_info_show(self, locations, clses, confs, path):
        """显示检测结果到表格"""
        for location, cls, conf in zip(locations, clses, confs):
            row_count = self.tableWidget.rowCount()
            self.tableWidget.insertRow(row_count)

            # 创建表格项
            item_id = QTableWidgetItem(str(row_count + 1))
            item_id.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

            item_path = QTableWidgetItem(str(path))

            item_cls = QTableWidgetItem(Config.CH_names[cls])
            item_cls.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

            item_conf = QTableWidgetItem(conf)
            item_conf.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

            item_location = QTableWidgetItem(str(location))

            # 设置表格项
            self.tableWidget.setItem(row_count, 0, item_id)
            self.tableWidget.setItem(row_count, 1, item_path)
            self.tableWidget.setItem(row_count, 2, item_cls)
            self.tableWidget.setItem(row_count, 3, item_conf)
            self.tableWidget.setItem(row_count, 4, item_location)

        self.tableWidget.scrollToBottom()

    # ===========================================
    # 保存功能方法组
    # ===========================================

    def save_detect(self):
        """保存检测结果"""
        if not hasattr(self, 'draw_img') and not self.cap:
            QMessageBox.about(self, '提示', '当前没有可保存信息，请先打开图片或视频！')
            return

        if self.is_camera_open:
            QMessageBox.about(self, '提示', '摄像头实时画面无法直接保存，请使用截图功能!')
            return

        if self.cap and self.timer_camera.isActive():
            res = QMessageBox.information(self, '提示', '保存视频检测结果可能需要较长时间，请确认是否继续保存？',
                                          QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            if res == QMessageBox.Yes:
                self.timer_camera.stop()
                self.save_thread = SaveThread(self.org_path, self.model, self.conf_thres, self.iou_thres,
                                              self.show_labels)
                self.save_thread.start()
                self.save_thread.update_ui_signal.connect(self.update_process_bar)
        else:
            if self.org_path and os.path.isfile(self.org_path):
                self.save_single_image()
            elif self.org_path and os.path.isdir(self.org_path):
                self.save_batch_images()

    def save_single_image(self):
        """保存单张图片检测结果"""
        fileName = os.path.basename(self.org_path)
        name, end_name = os.path.splitext(fileName)
        save_name = name + '_detect_result' + end_name
        save_img_path = os.path.join(Config.save_path, save_name)
        cv2.imwrite(save_img_path, self.draw_img)
        QMessageBox.about(self, '提示', f'图片保存成功!\n文件路径:{save_img_path}')

    def save_batch_images(self):
        """保存批量图片检测结果"""
        img_suffix = ['jpg', 'png', 'jpeg', 'bmp']
        QApplication.setOverrideCursor(Qt.WaitCursor)

        for file_name in os.listdir(self.org_path):
            full_path = os.path.join(self.org_path, file_name)
            if os.path.isfile(full_path) and file_name.split('.')[-1].lower() in img_suffix:
                results = self.model(full_path, conf=self.conf_thres, iou=self.iou_thres)[0]
                now_img = results.plot(labels=self.show_labels)
                name, end_name = os.path.splitext(file_name)
                save_name = name + '_detect_result' + end_name
                save_img_path = os.path.join(Config.save_path, save_name)
                cv2.imwrite(save_img_path, now_img)

        QApplication.restoreOverrideCursor()
        QMessageBox.about(self, '提示', f'批量图片保存成功!\n文件路径:{Config.save_path}')

    def update_process_bar(self, cur_num, total):
        """更新进度条"""
        if cur_num == 1:
            self.progress_bar = ProgressBar(self)
            self.progress_bar.show()

        if cur_num >= total:
            self.progress_bar.close()
            QMessageBox.about(self, '提示', f'视频保存成功!\n文件在{Config.save_path}目录下')
            return

        if not self.progress_bar.isVisible():
            self.save_thread.stop()
            return

        value = int(cur_num / total * 100)
        self.progress_bar.setValue(cur_num, total, value)
        QApplication.processEvents()

    # ===========================================
    # 参数更新方法组
    # ===========================================

    def update_conf_thres(self, value):
        """更新置信度阈值"""
        self.conf_thres = value
        self.redetect_if_possible()

    def update_iou_thres(self, value):
        """更新IoU阈值"""
        self.iou_thres = value
        self.redetect_if_possible()

    def update_show_labels(self, state):
        """更新标签显示状态"""
        self.show_labels = state == Qt.Checked
        self.redetect_if_possible()

    def redetect_if_possible(self):
        """在参数变化时重新检测"""
        if hasattr(self, 'org_path') and self.org_path and os.path.isfile(self.org_path) and not (
                self.cap and self.timer_camera.isActive()):
            self.detect_and_display(self.org_path)

    # ===========================================
    # 清理和关闭方法组
    # ===========================================

    def close_camera_if_open(self):
        """关闭摄像头"""
        if self.cap:
            self.cap.release()
            self.timer_camera.stop()
            self.is_camera_open = False
            self.CaplineEdit.setText('摄像头未开启')
            self.cap = None

    def clear_target_info(self):
        """清空目标信息显示"""
        self.type_lb.setText('')
        self.label_conf.setText('')
        self.label_xmin.setText('')
        self.label_ymin.setText('')
        self.label_xmax.setText('')
        self.label_ymax.setText('')

    def closeEvent(self, event):
        """程序退出时的资源清理"""
        try:
            self.close_camera_if_open()
            if hasattr(self, 'model'):
                del self.model
            event.accept()
        except Exception as e:
            print(f"⚠️ 资源清理失败: {e}")
            event.accept()


# todo
    # 在MainProgram.py中添加统计窗口集成代码
    def integrate_statistics_window(self):
        """集成统计窗口到主程序"""
        pass


    # 在MainProgram.py的MainWindow类中添加以下方法：

    def init_statistics_integration(self):
        """初始化统计功能集成"""
        """初始化统计功能集成"""
        if hasattr(self, 'stats_btn'):
            self.stats_btn.clicked.connect(self.show_statistics_window)
            # 设置工具提示
            self.stats_btn.setToolTip("""
               📊 数据统计分析

               功能特点：
               • 🏠 总览面板 - 关键指标一览
               • 📊 图表分析 - 多维度可视化
               • 🗺️ 空间分析 - 垃圾分布热力图
               • 🧠 智能评估 - AI水质等级评定
               • 📋 分析报告 - 专业环境评估报告

               支持导出Excel、JSON格式数据
               """)


    def show_statistics_window(self):
        """显示统计分析窗口"""
        try:
            # 检查是否有数据
            if not self.tableWidget or self.tableWidget.rowCount() == 0:
                QMessageBox.information(self, '提示',
                                        '当前没有检测数据！\n\n请先进行图片、视频或摄像头检测，生成数据后再查看统计分析。')
                return

            # 导入统计窗口
            from UIProgram.StatisticsWindow import StatisticsWindow

            # 创建并显示统计窗口
            self.statistics_window = StatisticsWindow(self, self.tableWidget)
            self.statistics_window.exec_()

        except ImportError as e:
            QMessageBox.warning(self, '错误',
                                f'统计分析模块导入失败:\n{str(e)}\n\n请确保已安装必要的依赖包：\n'
                                '• matplotlib\n• seaborn\n• pandas\n• numpy\n• scikit-learn\n• openpyxl')
            print(f"统计窗口导入失败: {e}")
        except Exception as e:
            QMessageBox.warning(self, '错误', f'统计窗口启动失败:\n{str(e)}')
            print(f"统计窗口启动失败: {e}")

class SaveThread(QThread):
    """
    视频保存线程类
    在后台处理视频检测结果保存，避免界面卡顿
    """
    update_ui_signal = pyqtSignal(int, int)

    def __init__(self, path, model, conf, iou, show_labels):
        super().__init__()
        self.org_path = path
        self.model = model
        self.conf = conf
        self.iou = iou
        self.show_labels = show_labels
        self.is_running = True

    def run(self):
        """执行视频保存任务"""
        cap = cv2.VideoCapture(self.org_path)
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        fps = cap.get(cv2.CAP_PROP_FPS)
        size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

        # 生成保存文件名
        fileName = os.path.basename(self.org_path)
        name, _ = os.path.splitext(fileName)
        save_name = name + '_detect_result.avi'
        save_video_path = os.path.join(Config.save_path, save_name)

        out = cv2.VideoWriter(save_video_path, fourcc, fps, size)
        total = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        cur_num = 0

        # 逐帧处理视频
        while cap.isOpened() and self.is_running:
            cur_num += 1
            ret, frame = cap.read()
            if ret:
                results = self.model(frame, conf=self.conf, iou=self.iou)[0]
                frame = results.plot(labels=self.show_labels)
                out.write(frame)
                self.update_ui_signal.emit(cur_num, total)
            else:
                break

        cap.release()
        out.release()

    def stop(self):
        """停止线程"""
        self.is_running = False


def setup_application():
    """
    设置应用程序基本信息和配置
    """
    app = QApplication(sys.argv)
    app.setApplicationName("AI智能水面垃圾检测系统")
    app.setApplicationVersion("2.0")
    app.setOrganizationName("EcoAI Labs")

    # 设置应用图标
    try:
        app_icon = QtGui.QIcon()
        app_icon.addPixmap(QtGui.QPixmap("UIProgram/ui_imgs/icons/目标检测.png"),
                           QtGui.QIcon.Normal, QtGui.QIcon.Off)
        app.setWindowIcon(app_icon)
    except Exception as e:
        print(f"应用图标设置失败: {e}")

    return app


if __name__ == "__main__":
    """
    主程序入口
    初始化应用程序并显示主窗口
    """
    try:
        # 创建应用程序
        app = setup_application()

        # 1. 创建并显示登录对话框
        login_dialog = LoginDialog()

        # 2. 检查登录结果
        # .exec_()会阻塞程序，直到对话框关闭
        if login_dialog.exec_() == QDialog.Accepted:
            # 3. 如果登录成功，则创建并显示主窗口
            win = MainWindow()
            win.show()
            sys.exit(app.exec_())  # 启动主应用的事件循环
        else:
            # 4. 如果用户取消登录，则退出程序
            sys.exit(0)

    except Exception as e:
        print(f"程序启动失败: {e}")
        # 使用QMessageBox显示更友好的错误信息
        error_box = QMessageBox()
        error_box.setIcon(QMessageBox.Critical)
        error_box.setText(f"程序启动时发生严重错误: {e}")
        error_box.setWindowTitle("启动失败")
        error_box.exec_()
        sys.exit(1)